home *** CD-ROM | disk | FTP | other *** search
- /*
- * misc.c -- Everything that isn't a callback or action.
- * Copyright (C) 1992 Timothy O. Theisen
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Author: Tim Theisen Systems Programmer
- * Internet: tim@cs.wisc.edu Department of Computer Sciences
- * UUCP: uwvax!tim University of Wisconsin-Madison
- * Phone: (608)262-0438 1210 West Dayton Street
- * FAX: (608)262-9777 Madison, WI 53706
- */
-
- #include <stdio.h>
- #ifndef SEEK_SET
- #define SEEK_SET 0
- #endif
-
- #include <X11/Xos.h>
- #include <signal.h>
- #ifdef SIGNALRETURNSINT
- #define SIGVAL int
- #else
- #define SIGVAL void
- #endif
-
- #include <math.h>
-
- #include <X11/Xatom.h>
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <X11/Shell.h>
- #include <X11/Xaw/Cardinals.h>
- #include <X11/Xaw/Form.h>
- #include <X11/Xaw/SimpleMenu.h>
- #include <X11/Xaw/SmeBSB.h>
- #include <X11/Xaw/SmeLine.h>
- #include <X11/Xaw/Scrollbar.h>
- #include <X11/Xaw/AsciiText.h>
- /* Yuck, cannot get vScrollbar via the usual methods */
- #include <X11/IntrinsicP.h>
- #include <X11/Xaw/TextP.h>
- #include <X11/Xmu/StdCmap.h>
-
- #include <errno.h>
- /* BSD 4.3 errno.h does not declare errno */
- extern int errno;
- #ifdef VMS
- #include <perror.h>
- #else
- extern int sys_nerr;
- extern char *sys_errlist[];
- #endif
-
- #include "Ghostview.h"
- #include "gv.h"
- #include "ps.h"
-
- #ifndef max
- #define max(a, b) ((a) > (b) ? (a) : (b))
- #endif
-
- /* Translate orientations defined by the enum in "ps.h" to
- * XtPageOrientations defined in "Ghostview.h".
- */
- static XtPageOrientation
- xorient(psorient)
- int psorient;
- {
- switch (psorient) {
- case PORTRAIT: return XtPageOrientationPortrait;
- case LANDSCAPE:
- if (app_res.swap_landscape) {
- return XtPageOrientationSeascape;
- } else {
- return XtPageOrientationLandscape;
- }
- }
- }
-
- static void
- break_chains()
- {
- Arg args[2];
- XtSetArg(args[0], XtNbottom, XtChainTop);
- XtSetArg(args[1], XtNright, XtChainLeft);
- XtSetValues(toc, args, ONE);
- XtSetValues(pageview, args, TWO);
- }
-
- static void
- set_chains()
- {
- Arg args[2];
-
- XtSetArg(args[0], XtNbottom, XtChainBottom);
- XtSetArg(args[1], XtNright, XtChainRight);
- XtSetValues(toc, args, ONE);
- XtSetValues(pageview, args, TWO);
- }
-
- static void
- reset_size_hints()
- {
- Arg args[4];
- if (app_res.ncdwm) return;
- XtSetArg(args[0], XtNmaxWidth, XtUnspecifiedShellInt);
- XtSetArg(args[1], XtNmaxHeight, XtUnspecifiedShellInt);
- XtSetArg(args[2], XtNminWidth, XtUnspecifiedShellInt);
- XtSetArg(args[3], XtNminHeight, XtUnspecifiedShellInt);
- XtSetValues(toplevel, args, FOUR);
- }
-
- static void
- set_size_hints(minw, minh, maxw, maxh)
- Dimension minw, minh, maxw, maxh;
- {
- Arg args[4];
-
- XtSetArg(args[0], XtNminWidth, minw);
- XtSetArg(args[1], XtNminHeight, minh);
- XtSetArg(args[2], XtNmaxWidth, maxw);
- XtSetArg(args[3], XtNmaxHeight, maxh);
- XtSetValues(toplevel, args, FOUR);
- }
-
- static Boolean horiz_scroll_saved = False;
- static Boolean vert_scroll_saved = False;
- static float horiz_top;
- static float vert_top;
-
- static void
- reset_scroll_bars()
- {
- Arg args[1];
- Widget scroll;
- float zero = 0.0;
-
- if (horiz_scroll_saved || vert_scroll_saved) return;
-
- scroll = XtNameToWidget(pageview, "horizontal");
- if (scroll) {
- XtSetArg(args[0], XtNtopOfThumb, &horiz_top);
- XtGetValues(scroll, args, ONE);
- XtCallCallbacks(scroll, XtNjumpProc, &zero);
- horiz_scroll_saved = True;
- }
-
- scroll = XtNameToWidget(pageview, "vertical");
- if (scroll) {
- XtSetArg(args[0], XtNtopOfThumb, &vert_top);
- XtGetValues(scroll, args, ONE);
- XtCallCallbacks(scroll, XtNjumpProc, &zero);
- vert_scroll_saved = True;
- }
- }
-
- static void
- set_scroll_bars()
- {
- Arg args[1];
- Widget scroll;
- float shown;
-
- if (horiz_scroll_saved) {
- scroll = XtNameToWidget(pageview, "horizontal");
- if (scroll) {
- XtSetArg(args[0], XtNshown, &shown);
- XtGetValues(scroll, args, ONE);
- if (horiz_top > (1.0 - shown)) horiz_top = (1.0 - shown);
- XtCallCallbacks(scroll, XtNjumpProc, &horiz_top);
- }
- }
-
- if (vert_scroll_saved) {
- scroll = XtNameToWidget(pageview, "vertical");
- if (scroll) {
- XtSetArg(args[0], XtNshown, &shown);
- XtGetValues(scroll, args, ONE);
- if (vert_top > (1.0 - shown)) vert_top = (1.0 - shown);
- XtCallCallbacks(scroll, XtNjumpProc, &vert_top);
- }
- }
-
- horiz_scroll_saved = vert_scroll_saved = False;
- }
-
- /* Start rendering a new page */
- void
- show_page(number)
- int number;
- {
- struct stat sbuf;
- int i;
-
- if (!filename) return;
-
- /* Unmark current_page as current */
- if (toc_text && (current_page >= 0)) {
- int marker = current_page*toc_entry_length + toc_entry_length-2;
- toc_text[marker] = ' ';
- XawTextInvalidate(toc, marker, marker+1);
- }
-
- /* If the file has changed, rescan it so that offsets into the file
- * are still correct. If the file is rescanned, we must setup ghostview
- * again. Also, force a new copy of ghostscript to start. */
- if (psfile) {
- if (!stat(filename, &sbuf) && mtime != sbuf.st_mtime) {
- fclose(psfile);
- psfile = fopen(filename, "r");
- mtime = sbuf.st_mtime;
- if (oldfilename) XtFree(oldfilename);
- oldfilename = XtNewString(filename);
- new_file(number);
- }
- }
-
- /* Coerce page number to fall in range */
- if (toc_text) {
- if (number >= doc->numpages) number = doc->numpages - 1;
- if (number < 0) number = 0;
- }
-
- if (set_new_orientation(number) || set_new_pagemedia(number))
- layout_ghostview();
-
- if (toc_text) {
- int marker;
- current_page = number;
- XawTextUnsetSelection(toc);
- XawTextSetInsertionPoint(toc, current_page * toc_entry_length);
- marker = current_page*toc_entry_length + toc_entry_length-2;
- toc_text[marker] = '<';
- XawTextInvalidate(toc, marker, marker+1);
- if (GhostviewIsInterpreterReady(page)) {
- GhostviewNextPage(page);
- } else {
- GhostviewEnableInterpreter(page);
- GhostviewSendPS(page, psfile, doc->beginprolog,
- doc->lenprolog, False);
- GhostviewSendPS(page, psfile, doc->beginsetup,
- doc->lensetup, False);
- }
- if (doc->pageorder == DESCEND)
- i = (doc->numpages - 1) - current_page;
- else
- i = current_page;
- GhostviewSendPS(page, psfile, doc->pages[i].begin,
- doc->pages[i].len, False);
- } else {
- if (!GhostviewIsInterpreterRunning(page))
- GhostviewEnableInterpreter(page);
- else if (GhostviewIsInterpreterReady(page))
- GhostviewNextPage(page);
- else
- XBell(XtDisplay(page), 0);
- }
-
- if (toc_text) {
- XtSetSensitive(prevbutton, current_page != 0);
- XtSetSensitive(nextbutton, current_page != doc->numpages-1);
- XtSetSensitive(showbutton, True);
- }
- }
-
- /* setup ghostview. This includes:
- * scanning the PostScript file,
- * setting the title and date labels,
- * building the pagemedia menu,
- * building the toc (table of contents)
- * sensitizing the appropriate menu buttons,
- * popping down and erasing the infotext popup.
- */
-
- static Boolean useful_page_labels;
- Boolean
- setup_ghostview()
- {
- Arg args[20];
- Cardinal num_args;
- int oldtoc_entry_length;
- char *tocp;
- XawTextBlock message_block;
- static String nothing = "";
- String label;
- Pixmap bitmap;
-
- /* Reset to a known state. */
- psfree(olddoc);
- olddoc = doc;
- doc = NULL;
- current_page = -1;
- if (toc_text) XtFree(toc_text);
- oldtoc_entry_length = toc_entry_length;
- toc_text = NULL;
-
- /* Scan document and start setting things up */
- if (psfile) doc = psscan(psfile);
-
- if (app_res.show_title) {
- if (doc && doc->title) {
- label = doc->title;
- bitmap = menu16_bitmap;
- } else {
- if (filename) {
- label = filename;
- } else {
- label = "";
- }
- bitmap = None;
- }
- XtSetArg(args[0], XtNlabel, label);
- XtSetValues(titlebutton, args, ONE);
- if (titlemenu) XtDestroyWidget(titlemenu);
- titlemenu = build_label_menu(titlebutton, "title", label, bitmap);
- }
-
- if (app_res.show_date) {
- if (doc && doc->date) {
- label = doc->date;
- bitmap = menu16_bitmap;
- } else {
- if (psfile) {
- label = ctime(&mtime);
- } else {
- label = "";
- }
- bitmap = None;
- }
- XtSetArg(args[0], XtNlabel, label);
- XtSetValues(datebutton, args, ONE);
- if (datemenu) XtDestroyWidget(datemenu);
- datemenu = build_label_menu(datebutton, "date", label, bitmap);
- }
-
- build_pagemedia_menu();
-
- /* Reset ghostscript and output messages popup */
- if (!doc || !olddoc ||
- strcmp(oldfilename, filename) ||
- olddoc->beginprolog != doc->beginprolog ||
- olddoc->endprolog != doc->endprolog ||
- olddoc->beginsetup != doc->beginsetup ||
- olddoc->endsetup != doc->endsetup) {
-
- GhostviewDisableInterpreter(page);
- XtPopdown(infopopup);
- info_up = False;
- XtSetArg(args[0], XtNeditType, XawtextEdit);
- XtSetArg(args[1], XtNinsertPosition, 0);
- XtSetValues(infotext, args, TWO);
- message_block.length = 0;
- XawTextReplace(infotext, 0, info_length, &message_block);
- info_length = 0;
- XtSetArg(args[0], XtNeditType, XawtextRead);
- XtSetValues(infotext, args, ONE);
- }
-
- /* Build table of contents */
- if (doc && (!doc->epsf && doc->numpages > 0 ||
- doc->epsf && doc->numpages > 1)) {
- int maxlen = 0;
- int i, j;
- useful_page_labels = False;
-
- if (doc->numpages == 1) useful_page_labels = True;
- for (i = 1; i < doc->numpages; i++)
- if (useful_page_labels = (useful_page_labels ||
- strcmp(doc->pages[i-1].label, doc->pages[i].label))) break;
- if (useful_page_labels) {
- for (i = 0; i < doc->numpages; i++)
- maxlen = max(maxlen, strlen(doc->pages[i].label));
- } else {
- double x;
- x = doc->numpages;
- maxlen = log10(x) + 1;
- }
- toc_entry_length = maxlen + 3;
- toc_length = doc->numpages * toc_entry_length - 1;
- toc_text = XtMalloc(toc_length + 2); /* include final NULL */
-
- for (i = 0, tocp = toc_text; i < doc->numpages;
- i++, tocp += toc_entry_length) {
- if (useful_page_labels) {
- if (doc->pageorder == DESCEND) {
- j = (doc->numpages - 1) - i;
- } else {
- j = i;
- }
- sprintf(tocp, " %*s \n", maxlen, doc->pages[j].label);
- } else {
- sprintf(tocp, " %*d \n", maxlen, i+1);
- }
- }
- toc_text[toc_length] = '\0';
- num_args = 0;
- XtSetArg(args[num_args], XtNfilename, NULL); num_args++;
- XtSetValues(page, args, num_args);
- } else {
- toc_length = 0;
- toc_entry_length = 3;
- num_args = 0;
- XtSetArg(args[num_args], XtNfilename, filename); num_args++;
- XtSetValues(page, args, num_args);
- }
- num_args = 0;
- XtSetArg(args[num_args], XtNlength, toc_length); num_args++;
- if (toc_text) {
- XtSetArg(args[num_args], XtNstring, toc_text); num_args++;
- } else {
- /* Text widget sometime blows up when given a NULL pointer */
- XtSetArg(args[num_args], XtNstring, nothing); num_args++;
- }
- XtSetValues(toc, args, num_args);
-
- XtSetSensitive(reopenbutton, (psfile != NULL));
- XtSetSensitive(printwholebutton, (psfile != NULL));
- XtSetSensitive(printmarkedbutton, (psfile != NULL));
- XtSetSensitive(savebutton, (toc_text != NULL));
- XtSetSensitive(nextbutton, (filename != NULL));
- XtSetSensitive(showbutton, (filename != NULL));
- XtSetSensitive(prevbutton, (toc_text != NULL));
- XtSetSensitive(centerbutton, (filename != NULL));
- XtSetSensitive(markbutton, (toc_text != NULL));
- XtSetSensitive(unmarkbutton, (toc_text != NULL));
-
- return oldtoc_entry_length != toc_entry_length;
- }
-
- int
- find_page(label)
- String label;
- {
- int i, j;
-
- if (label == NULL || doc == NULL) return 0;
-
- if (useful_page_labels) {
- for (i = 0; i < doc->numpages; i++) {
- if (doc->pageorder == DESCEND) {
- j = (doc->numpages - 1) - i;
- } else {
- j = i;
- }
- if (!strcmp(label, doc->pages[j].label)) return i;
- }
- return 0;
- } else {
- return atoi(label) - 1;
- }
- }
-
- /* try_try_again sets the geometry of the form when the form failed
- * to do it earlier. It uses activity check with exponential backoff
- * to make sure that the dust has settled before trying again.
- */
- static unsigned int delay = 125; /* Start with 1/8 second delay */
-
- static void
- try_try_again(client_data, timer)
- XtPointer client_data;
- XtIntervalId *timer;
- {
- XSync(XtDisplay(toplevel), False); /* Push everything out */
- if (XtAppPending(app_con)) {
- XtAppAddTimeOut(app_con, delay, try_try_again, NULL);
- /* fprintf(stderr, "Delaying(%d)...\n",delay); */
- delay *= 2;
- } else {
- /* fprintf(stderr, "Trying again...\n"); */
- layout_ghostview();
- }
- }
-
- /* set the dimensions for items in the main form widget. */
- /* set foreground and background color in scrollbars. */
- /* (The scroll bars come and go as size changes.) */
- /* Set window manager hints to keep window manager from causing main */
- /* viewport from growing too large */
- void
- layout_ghostview()
- {
- Arg args[20];
- Dimension min_width, min_height;
- Dimension max_width, max_height;
- Dimension form_width, form_height;
- Dimension title_height, title_border;
- Dimension date_height, date_border;
- Dimension locator_height, locator_border;
- Dimension box_width, box_height, box_border;
- Dimension label_width;
- Dimension toc_width, toc_height, toc_border;
- Dimension view_width, view_height, view_border;
- Dimension page_width, page_height;
- Dimension leftMargin, rightMargin;
- Dimension width, height;
- Boolean correct = True;
- int distance;
- int a_label;
- XFontStruct *font;
-
- XawFormDoLayout(form, False);
- reset_size_hints();
- reset_scroll_bars();
- break_chains();
-
- XtSetArg(args[0], XtNdefaultDistance, &distance);
- XtGetValues(form, args, ONE);
-
- a_label = 0;
- if (app_res.show_title) {
- XtSetArg(args[0], XtNheight, &title_height);
- XtSetArg(args[1], XtNborderWidth, &title_border);
- XtGetValues(titlebutton, args, TWO);
- a_label = 1;
- } else {
- title_height = title_border = 0;
- }
-
- if (app_res.show_date) {
- XtSetArg(args[0], XtNheight, &date_height);
- XtSetArg(args[1], XtNborderWidth, &date_border);
- XtGetValues(datebutton, args, TWO);
- a_label = 1;
- } else {
- date_height = date_border = 0;
- }
-
- if (app_res.show_locator) {
- XtSetArg(args[0], XtNheight, &locator_height);
- XtSetArg(args[1], XtNborderWidth, &locator_border);
- XtGetValues(locator, args, TWO);
- a_label = 1;
- } else {
- locator_height = locator_border = 0;
- }
-
- XtSetArg(args[0], XtNwidth, &box_width);
- XtSetArg(args[1], XtNheight, &box_height);
- XtSetArg(args[2], XtNborderWidth, &box_border);
- XtGetValues(box, args, THREE);
-
- XtSetArg(args[0], XtNfont, &font);
- XtSetArg(args[1], XtNleftMargin, &leftMargin);
- XtSetArg(args[2], XtNrightMargin, &rightMargin);
- XtSetArg(args[3], XtNborderWidth, &toc_border);
- XtGetValues(toc, args, FOUR);
- toc_width = font->max_bounds.width * (toc_entry_length - 1) +
- leftMargin + rightMargin;
-
- XtSetArg(args[0], XtNwidth, &page_width);
- XtSetArg(args[1], XtNheight, &page_height);
- XtGetValues(page, args, TWO);
-
- XtSetArg(args[0], XtNborderWidth, &view_border);
- XtGetValues(pageview, args, ONE);
- view_width = page_width;
- view_height = page_height;
-
- min_width = box_width + 2*box_border + toc_width + 2*toc_border +
- 2*view_border + 4*distance;
- min_height = title_height + 2*title_border + date_height + 2*date_border +
- locator_height + 2*locator_border + box_height + 2*box_border +
- (2+a_label)*distance;
-
- max_width = WidthOfScreen(XtScreen(toplevel)) - app_res.wm_horiz_margin;
- max_height = HeightOfScreen(XtScreen(toplevel)) - app_res.wm_vert_margin;
-
- if (min_width + view_width > max_width)
- view_width = max_width - min_width;
- if (2*(view_border + distance) + view_height > max_height)
- view_height = max_height - 2*(view_border + distance);
- form_width = view_width + min_width;
- form_height = max(view_height + 2*(view_border + distance), min_height);
- toc_height = view_height - (title_height + 2*title_border +
- date_height + 2*date_border +
- locator_height + 2*locator_border +
- a_label*distance);
-
- label_width = box_width + 2*box_border + distance +
- toc_width + 2*toc_border;
-
- XtSetArg(args[0], XtNwidth, form_width);
- XtSetArg(args[1], XtNheight, form_height);
- XtSetValues(form, args, TWO);
-
- XtSetArg(args[0], XtNwidth, label_width);
- if (app_res.show_title) XtSetValues(titlebutton, args, ONE);
- if (app_res.show_date) XtSetValues(datebutton, args, ONE);
- if (app_res.show_locator) XtSetValues(locator, args, ONE);
-
- XtSetArg(args[0], XtNwidth, toc_width);
- XtSetArg(args[1], XtNheight, toc_height);
- XtSetValues(toc, args, TWO);
-
- XtSetArg(args[0], XtNwidth, view_width);
- XtSetArg(args[1], XtNheight, view_height);
- XtSetValues(pageview, args, TWO);
-
- XawFormDoLayout(form, True);
-
- /* Check to make sure everything was done as planned. */
- XtSetArg(args[0], XtNwidth, &width);
- XtSetArg(args[1], XtNheight, &height);
-
- XtGetValues(form, args, TWO);
- if (width != form_width || height != form_height) {
- correct = False;
- /* fprintf(stderr, "Oops, %dx%d form was supposed to be %dx%d.\n",
- width, height, form_width, form_height); */
- }
- if (app_res.show_title) {
- XtGetValues(titlebutton, args, ONE);
- if (width != label_width) {
- correct = False;
- /* fprintf(stderr,
- "Oops, %d wide title was supposed to be %d wide.\n",
- width, label_width); */
- }
- }
- if (app_res.show_date) {
- XtGetValues(datebutton, args, ONE);
- if (width != label_width) {
- correct = False;
- /* fprintf(stderr,
- "Oops, %d wide date was supposed to be %d wide.\n",
- width, label_width); */
- }
- }
- if (app_res.show_locator) {
- XtGetValues(locator, args, ONE);
- if (width != label_width) {
- correct = False;
- /* fprintf(stderr,
- "Oops, %d wide locator was supposed to be %d wide.\n",
- width, label_width); */
- }
- }
- XtGetValues(toc, args, TWO);
- if (width != toc_width || height != toc_height) {
- correct = False;
- /* fprintf(stderr, "Oops, %dx%d toc was supposed to be %dx%d.\n",
- width, height, toc_width, toc_height); */
- }
- XtGetValues(pageview, args, TWO);
- if (width != view_width || height != view_height) {
- correct = False;
- /* fprintf(stderr, "Oops, %dx%d pageview was supposed to be %dx%d.\n",
- width, height, view_width, view_height); */
- }
-
- if (correct) {
- set_size_hints(min_width, min_height, min_width+page_width,
- max(form_height,
- page_height + 2*(view_border + distance)));
- if (app_res.auto_center) {
- horiz_scroll_saved = vert_scroll_saved = False;
- center_page(form, NULL, NULL);
- } else {
- set_scroll_bars();
- }
- set_chains();
- delay = 125; /* Reset to 1/8 second delay */
- /* fprintf(stderr, "Layout correct.\n"); */
- } else {
- XSync(XtDisplay(toplevel), False);
- XtAppAddTimeOut(app_con, delay, try_try_again, NULL);
- /* fprintf(stderr, "Didn't work, scheduling(%d)...\n",delay); */
- }
-
- }
-
- /* Compute new dpi from magstep */
- void
- magnify(dpi, magstep)
- float *dpi;
- int magstep;
- {
- if (magstep < 0) {
- while (magstep++) *dpi /= 1.2;
- } else {
- while (magstep--) *dpi *= 1.2;
- }
- }
-
- /* Attempt to open file, return error message string on failure */
- String
- open_file(name)
- String name;
- {
- FILE *fp;
- struct stat sbuf;
-
- if (*name == '\0') { /* Null filename */
- return(NULL);
- }
- if (strcmp(name, "-")) {
- if ((fp = fopen(name, "r")) == NULL) {
- String buf = XtMalloc(strlen(app_res.open_fail) +
- strlen(sys_errlist[errno]) + 1);
- strcpy(buf, app_res.open_fail);
- if (errno <= sys_nerr) strcat(buf, sys_errlist[errno]);
- return buf;
- } else {
- if (oldfilename) XtFree(oldfilename);
- oldfilename = filename;
- filename = XtNewString(name);
- if (psfile) fclose(psfile);
- psfile = fp;
- stat(filename, &sbuf);
- mtime = sbuf.st_mtime;
- new_file(0);
- show_page(0);
- return(NULL);
- }
- } else {
- if (oldfilename) XtFree(oldfilename);
- oldfilename = filename;
- filename = XtNewString(name);
- if (psfile) fclose(psfile);
- psfile = NULL;
- new_file(0);
- show_page(0);
- return(NULL);
- }
- }
-
- /* Attempt to save file, return error message string on failure */
- String
- save_file(name)
- String name;
- {
- FILE *pswrite;
-
- if (*name == '\0') { /* Null filename */
- return(NULL);
- }
- if ((pswrite = fopen(name, "w")) == NULL) {
- String buf = XtMalloc(strlen(app_res.save_fail) +
- strlen(sys_errlist[errno]) + 1);
- strcpy(buf, app_res.save_fail);
- if (errno <= sys_nerr) strcat(buf, sys_errlist[errno]);
- return buf;
- } else {
- pscopydoc(pswrite);
- fclose(pswrite);
- return(NULL);
- }
- }
-
- /* Attempt to print file. Return error string on failure */
- String
- print_file(name, whole_mode)
- String name;
- Boolean whole_mode;
- {
- FILE *printer;
- SIGVAL (*oldsig)();
- int bytes;
- char buf[BUFSIZ];
- #ifdef VMS
- char fnam[64], *p;
- #endif
- Boolean failed;
- String ret_val;
-
- #ifdef VMS
- sprintf(fnam, "sys$scratch:%s.tmp", tmpnam(NULL));
- printer = fopen(fnam, "w");
- #else /* VMS */
- if (*name != '\0') {
- setenv(app_res.printer_variable, name, True);
- }
- oldsig = signal(SIGPIPE, SIG_IGN);
- printer = popen(app_res.print_command, "w");
- #endif /* VMS */
- if (toc_text && !whole_mode) {
- pscopydoc(printer);
- } else {
- FILE *psfile = fopen(filename, "r");
- while (bytes = read(fileno(psfile), buf, BUFSIZ))
- bytes = write(fileno(printer), buf, bytes);
- fclose(psfile);
- }
- #ifdef VMS
- sprintf(buf, "%s %s %s", app_res.print_command, name, fnam);
- failed = fclose(printer) != 0 || system(buf) != 1;
- #else /* VMS */
- failed = pclose(printer) != 0;
- #endif /* VMS */
- if (failed) {
- sprintf(buf, app_res.print_fail, app_res.print_command);
- ret_val = XtNewString(buf);
- } else {
- ret_val = NULL;
- }
- #ifndef VMS
- signal(SIGPIPE, oldsig);
- #endif /* VMS */
- return(ret_val);
- }
-
- /* length calculates string length at compile time */
- /* can only be used with character constants */
- #define length(a) (sizeof(a)-1)
-
- /* Copy the headers, marked pages, and trailer to fp */
- void
- pscopydoc(fp)
- FILE *fp;
- {
- FILE *psfile;
- char text[PSLINELENGTH];
- char *comment;
- Boolean pages_written = False;
- Boolean pages_atend = False;
- Boolean marked_pages = False;
- int pages = 0;
- int page = 1;
- int i, j;
- long here;
-
- psfile = fopen(filename, "r");
-
- for (i = 0; i < doc->numpages; i++) {
- if (toc_text[toc_entry_length * i] == '*') pages++;
- }
-
- if (pages == 0) { /* User forgot to mark the pages */
- mark_page(form, NULL, NULL);
- marked_pages = True;
- for (i = 0; i < doc->numpages; i++) {
- if (toc_text[toc_entry_length * i] == '*') pages++;
- }
- }
-
- here = doc->beginheader;
- while (comment = pscopyuntil(psfile, fp, here,
- doc->endheader, "%%Pages:")) {
- here = ftell(psfile);
- if (pages_written || pages_atend) {
- free(comment);
- continue;
- }
- sscanf(comment+length("%%Pages:"), "%s", text);
- if (strcmp(text, "(atend)") == 0) {
- fputs(comment, fp);
- pages_atend = True;
- } else {
- switch (sscanf(comment+length("%%Pages:"), "%*d %d", &i)) {
- case 1:
- fprintf(fp, "%%%%Pages: %d %d\n", pages, i);
- break;
- default:
- fprintf(fp, "%%%%Pages: %d\n", pages);
- break;
- }
- pages_written = True;
- }
- free(comment);
- }
- pscopy(psfile, fp, doc->beginpreview, doc->endpreview);
- pscopy(psfile, fp, doc->begindefaults, doc->enddefaults);
- pscopy(psfile, fp, doc->beginprolog, doc->endprolog);
- pscopy(psfile, fp, doc->beginsetup, doc->endsetup);
-
- for (i = 0; i < doc->numpages; i++) {
- if (doc->pageorder == DESCEND)
- j = (doc->numpages - 1) - i;
- else
- j = i;
- if (toc_text[toc_entry_length * j] == '*') {
- comment = pscopyuntil(psfile, fp, doc->pages[i].begin,
- doc->pages[i].end, "%%Page:");
- fprintf(fp, "%%%%Page: %s %d\n",
- doc->pages[i].label, page++);
- free(comment);
- pscopy(psfile, fp, -1, doc->pages[i].end);
- }
- }
-
- here = doc->begintrailer;
- while (comment = pscopyuntil(psfile, fp, here,
- doc->endtrailer, "%%Pages:")) {
- here = ftell(psfile);
- if (pages_written) {
- free(comment);
- continue;
- }
- switch (sscanf(comment+length("%%Pages:"), "%*d %d", &i)) {
- case 1:
- fprintf(fp, "%%%%Pages: %d %d\n", pages, i);
- break;
- default:
- fprintf(fp, "%%%%Pages: %d\n", pages);
- break;
- }
- pages_written = True;
- free(comment);
- }
- fclose(psfile);
-
- if (marked_pages) unmark_page(form, NULL, NULL);
- }
- #undef length
-
- /* position popup window under the cursor */
- void
- positionpopup(w)
- Widget w;
- {
- Arg args[3];
- Cardinal num_args;
- Dimension width, height, b_width;
- int x, y, max_x, max_y;
- Window root, child;
- int dummyx, dummyy;
- unsigned int dummymask;
-
- XQueryPointer(XtDisplay(w), XtWindow(w), &root, &child, &x, &y,
- &dummyx, &dummyy, &dummymask);
- num_args = 0;
- XtSetArg(args[num_args], XtNwidth, &width); num_args++;
- XtSetArg(args[num_args], XtNheight, &height); num_args++;
- XtSetArg(args[num_args], XtNborderWidth, &b_width); num_args++;
- XtGetValues(w, args, num_args);
-
- width += 2 * b_width;
- height += 2 * b_width;
-
- x -= ( (Position) width/2 );
- if (x < 0) x = 0;
- if ( x > (max_x = (Position) (XtScreen(w)->width - width)) ) x = max_x;
-
- y -= ( (Position) height/2 );
- if (y < 0) y = 0;
- if ( y > (max_y = (Position) (XtScreen(w)->height - height)) ) y = max_y;
-
- num_args = 0;
- XtSetArg(args[num_args], XtNx, x); num_args++;
- XtSetArg(args[num_args], XtNy, y); num_args++;
- XtSetValues(w, args, num_args);
- }
-
- /* Set new magstep */
- Boolean
- set_new_magstep()
- {
- int new_magstep;
- Boolean changed = False;
- Arg args[20];
- Cardinal num_args;
- float xdpi, ydpi;
-
- new_magstep = app_res.magstep;
- /* If magstep changed, stop interpreter and setup for new dpi. */
- if (new_magstep != current_magstep) {
- GhostviewDisableInterpreter(page);
- XawFormDoLayout(form, False);
- reset_size_hints();
- reset_scroll_bars();
- break_chains();
- changed = True;
- xdpi = default_xdpi;
- ydpi = default_ydpi;
- magnify(&xdpi, new_magstep);
- magnify(&ydpi, new_magstep);
- num_args = 0;
- XtSetFloatArg(args[num_args], XtNxdpi, xdpi); num_args++;
- XtSetFloatArg(args[num_args], XtNydpi, ydpi); num_args++;
- XtSetValues(page, args, num_args);
-
- XtSetArg(args[0], XtNleftBitmap, None);
- XtSetValues(magstepentry[current_magstep - app_res.minimum_magstep],
- args, ONE);
- current_magstep = new_magstep;
- }
- XtSetArg(args[0], XtNleftBitmap, dot_bitmap);
- XtSetValues(magstepentry[current_magstep - app_res.minimum_magstep],
- args, ONE);
-
- return changed;
- }
-
- /* Set new orientation */
- Boolean
- set_new_orientation(number)
- int number;
- {
- Boolean changed = False;
- Boolean from_doc = False;
- Arg args[1];
- XtPageOrientation new_orientation;
-
- if (app_res.force_orientation) {
- new_orientation = app_res.orientation;
- } else {
- if (doc) {
- if (toc_text && doc->pages[number].orientation != NONE) {
- new_orientation = xorient(doc->pages[number].orientation);
- from_doc = True;
- } else if (doc->default_page_orientation != NONE) {
- new_orientation = xorient(doc->default_page_orientation);
- from_doc = True;
- } else if (doc->orientation != NONE) {
- new_orientation = xorient(doc->orientation);
- from_doc = True;
- } else {
- new_orientation = app_res.orientation;
- }
- } else {
- new_orientation = app_res.orientation;
- }
- }
-
- /* If orientation changed,
- * stop interpreter and setup for new orientation. */
- if (new_orientation != current_orientation) {
- GhostviewDisableInterpreter(page);
- XawFormDoLayout(form, False);
- reset_size_hints();
- reset_scroll_bars();
- break_chains();
- changed = True;
- XtSetArg(args[0], XtNorientation, new_orientation);
- XtSetValues(page, args, ONE);
- XtSetArg(args[0], XtNleftBitmap, None);
- if (current_orientation == XtPageOrientationPortrait)
- XtSetValues(portraitbutton, args, ONE);
- else if (current_orientation == XtPageOrientationLandscape)
- XtSetValues(landscapebutton, args, ONE);
- else if (current_orientation == XtPageOrientationUpsideDown)
- XtSetValues(upsidedownbutton, args, ONE);
- else if (current_orientation == XtPageOrientationSeascape)
- XtSetValues(seascapebutton, args, ONE);
- current_orientation = new_orientation;
- }
-
- /* mark forced orientation with tie fighter. ("Use the force, Luke") */
- if (app_res.force_orientation) {
- XtSetArg(args[0], XtNleftBitmap, tie_fighter_bitmap);
- } else if (from_doc) {
- XtSetArg(args[0], XtNleftBitmap, menu16_bitmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, dot_bitmap);
- }
- if (current_orientation == XtPageOrientationPortrait)
- XtSetValues(portraitbutton, args, ONE);
- else if (current_orientation == XtPageOrientationLandscape)
- XtSetValues(landscapebutton, args, ONE);
- else if (current_orientation == XtPageOrientationUpsideDown)
- XtSetValues(upsidedownbutton, args, ONE);
- else if (current_orientation == XtPageOrientationSeascape)
- XtSetValues(seascapebutton, args, ONE);
-
- return changed;
- }
-
- /* Set new pagemedia */
- Boolean
- set_new_pagemedia(number)
- int number;
- {
- int new_pagemedia;
- int new_llx;
- int new_lly;
- int new_urx;
- int new_ury;
- Boolean changed = False;
- Boolean from_doc = False;
- Arg args[4];
-
- if (force_document_media) {
- new_pagemedia = document_media;
- } else if (app_res.force_pagemedia) {
- new_pagemedia = default_pagemedia;
- } else {
- if (doc) {
- if (toc_text && doc->pages[number].media != NULL) {
- new_pagemedia = doc->pages[number].media - doc->media;
- from_doc = True;
- } else if (doc->default_page_media != NULL) {
- new_pagemedia = doc->default_page_media - doc->media;
- from_doc = True;
- } else {
- new_pagemedia = default_pagemedia;
- }
- } else {
- new_pagemedia = default_pagemedia;
- }
- }
-
- /* If pagemedia changed, remove the old marker. */
- if (new_pagemedia != current_pagemedia) {
- XtSetArg(args[0], XtNleftBitmap, None);
- if (pagemediaentry[current_pagemedia])
- XtSetValues(pagemediaentry[current_pagemedia], args, ONE);
- else
- XtSetValues(pagemediaentry[current_pagemedia-1], args, ONE);
-
- current_pagemedia = new_pagemedia;
- }
-
- /* mark forced page media with tie fighter. ("Use the force, Luke") */
- if (force_document_media || app_res.force_pagemedia) {
- XtSetArg(args[0], XtNleftBitmap, tie_fighter_bitmap);
- } else if (from_doc) {
- XtSetArg(args[0], XtNleftBitmap, menu16_bitmap);
- } else {
- XtSetArg(args[0], XtNleftBitmap, dot_bitmap);
- }
- if (pagemediaentry[current_pagemedia])
- XtSetValues(pagemediaentry[current_pagemedia], args, ONE);
- else
- XtSetValues(pagemediaentry[current_pagemedia-1], args, ONE);
-
- /* Compute bounding box */
- if (!force_document_media && !app_res.force_pagemedia &&
- doc && doc->epsf &&
- /* Ignore malformed bounding boxes */
- (doc->boundingbox[URX] > doc->boundingbox[LLX]) &&
- (doc->boundingbox[URY] > doc->boundingbox[LLY])) {
- new_llx = doc->boundingbox[LLX];
- new_lly = doc->boundingbox[LLY];
- new_urx = doc->boundingbox[URX];
- new_ury = doc->boundingbox[URY];
- } else {
- new_llx = new_lly = 0;
- if (new_pagemedia < base_papersize) {
- new_urx = doc->media[new_pagemedia].width;
- new_ury = doc->media[new_pagemedia].height;
- } else {
- new_urx = papersizes[new_pagemedia-base_papersize].width;
- new_ury = papersizes[new_pagemedia-base_papersize].height;
- }
- }
-
- /* If bounding box changed, setup for new size. */
- if ((new_llx != current_llx) || (new_lly != current_lly) ||
- (new_urx != current_urx) || (new_ury != current_ury)) {
- GhostviewDisableInterpreter(page);
- XawFormDoLayout(form, False);
- reset_size_hints();
- reset_scroll_bars();
- break_chains();
- changed = True;
- current_llx = new_llx;
- current_lly = new_lly;
- current_urx = new_urx;
- current_ury = new_ury;
- XtSetArg(args[0], XtNllx, current_llx);
- XtSetArg(args[1], XtNlly, current_lly);
- XtSetArg(args[2], XtNurx, current_urx);
- XtSetArg(args[3], XtNury, current_ury);
- XtSetValues(page, args, FOUR);
- }
-
- return changed;
- }
-
- static Boolean
- same_document_media()
- {
- int i;
-
- if (olddoc == NULL && doc == NULL) return True;
- if (olddoc == NULL || doc == NULL) return False;
- if (olddoc->nummedia != doc->nummedia) return False;
- for (i = 0; i < doc->nummedia; i++)
- if (strcmp(olddoc->media[i].name, doc->media[i].name)) return False;
- return True;
- }
-
- void
- build_pagemedia_menu()
- {
- Arg args[20];
- Cardinal num_args;
- Widget w;
- int i;
-
- if (pagemediamenu && same_document_media()) return;
- if (pagemediamenu) XtDestroyWidget(pagemediamenu);
- force_document_media = False;
-
- pagemediamenu = XtCreatePopupShell("menu", simpleMenuWidgetClass,
- pagemediabutton, NULL, ZERO);
-
- /* Build the Page Media menu */
- /* the Page media menu has two parts.
- * - the document defined page medias
- * - the standard page media defined from Adobe's PPD
- */
- base_papersize = 0;
- if (doc) base_papersize = doc->nummedia;
- for (i = 0; papersizes[i].name; i++) {} /* Count the standard entries */
- i += base_papersize;
- pagemediaentry = (Widget *) XtMalloc(i * sizeof(Widget));
-
- if (doc && doc->nummedia) {
- for (i = 0; i < doc->nummedia; i++) {
- num_args = 0;
- XtSetArg(args[num_args], XtNleftMargin, 20); num_args++;
- pagemediaentry[i] = XtCreateManagedWidget(doc->media[i].name,
- smeBSBObjectClass, pagemediamenu,
- args, num_args);
- XtAddCallback(pagemediaentry[i], XtNcallback,
- set_pagemedia, (XtPointer)i);
- }
-
- num_args = 0;
- w = XtCreateManagedWidget("line", smeLineObjectClass, pagemediamenu,
- args, num_args);
- }
-
- for (i = 0; papersizes[i].name; i++) {
- pagemediaentry[i+base_papersize] = NULL;
- if (i > 0) {
- /* Skip over same paper size with small imageable area */
- if ((papersizes[i].width == papersizes[i-1].width) &&
- (papersizes[i].height == papersizes[i-1].height)) {
- continue;
- }
- }
- num_args = 0;
- XtSetArg(args[num_args], XtNleftMargin, 20); num_args++;
- pagemediaentry[i+base_papersize] = XtCreateManagedWidget(
- papersizes[i].name,
- smeBSBObjectClass, pagemediamenu,
- args, num_args);
- XtAddCallback(pagemediaentry[i+base_papersize], XtNcallback,
- set_pagemedia, (XtPointer)(i+base_papersize));
- }
- }
-
- Widget
- build_label_menu(parent, name, label, bitmap)
- Widget parent;
- String name, label;
- Pixmap bitmap;
- {
- Arg args[20];
- Cardinal num_args;
- Widget menu, entry;
- num_args = 0;
- menu = XtCreatePopupShell("menu", simpleMenuWidgetClass,
- parent, args, num_args);
-
- num_args = 0;
- XtSetArg(args[num_args], XtNlabel, label); num_args++;
- if (bitmap) {
- XtSetArg(args[num_args], XtNleftMargin, 20); num_args++;
- XtSetArg(args[num_args], XtNleftBitmap, bitmap); num_args++;
- }
- entry = XtCreateManagedWidget(name, smeBSBObjectClass,
- menu, args, num_args);
- return menu;
- }
-
- void
- new_file(number)
- int number;
- {
- Boolean layout_changed = False;
-
- if (setup_ghostview()) layout_changed = True;
-
- /* Coerce page number to fall in range */
- if (toc_text) {
- if (number >= doc->numpages) number = doc->numpages - 1;
- if (number < 0) number = 0;
- }
-
- if (set_new_orientation(number)) layout_changed = True;
- if (set_new_pagemedia(number)) layout_changed = True;
- if (layout_changed) layout_ghostview();
- }
-
- /* Catch X errors die gracefully if one occurs */
- int
- catch_Xerror(dpy, err)
- Display *dpy;
- XErrorEvent *err;
- {
- if (err->error_code == BadImplementation) {
- old_Xerror(dpy, err);
- return 0;
- }
- if (dying) return 0;
- dying = True;
- bomb = *err;
- XtDestroyWidget(toplevel);
- return 0;
- }
-